/**
*@date 2011-09-07
*@auth xiongsh
*@desc pui核心库及命名空间定义
*/

/***定义命名空间*/
Mui={
	version:'1.0.0',
	backCompat:document.compatMode=='BackCompat'?true:false
};

/***@desc 定义基础方法*/
(function(){
	/**
	*@description 覆盖多个object的方法,scope将作为保留关键字,用于传递作用域
	*@param o:目标对象
	*@param c:源对象，注意：源对象可以为多个,分多个参数传递
	*/
	Mui.apply=function(o,c){
		if(!o||!c||typeof(c)!='object'){
			return;
		}
		
		for(var p in c){
			o[p]=c[p];
		}
		
		for(var i=2;i<arguments.length;i++){
			arguments.callee(o,arguments[i]);
		}
	};
	
	Mui.apply(Mui,{
		/**
		*@description 合并多个object的方法,本方法只将o中不存在（即值为undefined）的属性,将c中对应的属性进行覆盖
		*@param o: 目标对象
		*@param c:源对象，注意：源对象可以为多个，分多个参数传递
		*@return null
		*/
		applyIf:function(o,c){
			if(!o||!c||typeof(c)!='object'){
				return;
			}	
			for(var p in c){
				if(o[p]==undefined){
					o[p]=c[p];
				}			
			}		
			for(var i=2;i<arguments.length;i++){
				arguments.callee(o,arguments[i]);
			}		
		},
		/**
		*@desc 删除属性
		*@param dels：需要删除的属性的数组
		*/
		delApply:function(o,dels){
			if(dels){
				for(var i=0,len=dels.length;i<len;i++){
					delete o[c[i]];
				}
			}
		},
		/**
		*@description 覆盖多个object的方法,scope将作为保留关键字，用于传递作用域，深度复制
		*@param o:目标对象
		*@param c:源对象，注意：源对象可以为多个，分多个参数传递
		*/
		deepApply:function(o,c){		
			if(!o||!c||typeof(c)!='object'){
				return;
			}		
			for(var p in c){
				if(p=='scope'){
					o.scope=c.scope;
				}else{
					if(typeof(c[p])=='object'){
						if(c[p] instanceof Array){
							o[p]=c[p].concat();
						}else if(c[p]==null){
							o[p]=null;
						}else{
							o[p]={};
							Mui.deepApply(o[p],c[p]);
						}
					}else{
						o[p]=c[p];
					}
				}
			}		
			for(var i=2;i<arguments.length;i++){
				arguments.callee(o,arguments[i]);
			}
		},
		/**
		*@description 合并多个object的方法,本方法只将o中不存在（即值为undefined）的属性,将c中对应的属性进行覆盖，深度复制
		*@param o:目标对象
		*@param c:源对象，注意：源对象可以为多个，分多个参数传递
		*/
		deepApplyIf:function(o,c){
			if(!o||!c||typeof(c)!='object'){
				return;
			}
			
			for(var p in c){
				if(o[p]==undefined){
					if(typeof(c[p]=='object')){
						if(c[p] instanceof Array){
							o[p]=c[s].concat();
						}else if(c[p]==null){
							o[p]=null;
						}else{
							o[p]={};
							Mui.applyIf(o[p],c[p]);
						}
					}else{
						o[p]=c[p];
					}
				}
			}
			
			for(var i=2;i<arguments.length;i++){
				arguments.callee(o,arguments[i]);
			}
		},
		/*
		*@desc 命名空间定义函数
		*/
		ns:function(){
			var a=arguments, o=null, i, j, d, rt;
			for (i=0; i<a.length; ++i) {
				d=a[i].split(".");
				rt = d[0];
				eval('if (typeof ' + rt + ' == "undefined"){' + rt + ' = {};} o = ' + rt + ';');
				for (j=1; j<d.length; ++j) {
					o[d[j]]=o[d[j]] || {};
					o=o[d[j]];
				}
			}
		},
		/**
		*@desc 类继承
		*/
		extend:function(superclass,exconfig){
			var clazz=function(config){
				Mui.deepApply(this,this.constructor.basedata);
				Mui.apply(this,config);
				this.initComponent=this.initComponent||function(){};				
				this.initComponent();
			};
			if(!arguments.length){
				return clazz;
			}		
			var cp=clazz.prototype;	
			if(superclass){
				var sp=superclass.prototype;
				
				var f=function(){};
				f.prototype=sp;
				cp=new f();
				cp.constructor=clazz;
				clazz.superclass=sp;
				clazz.prototype.superclass=sp;
			}
			if(exconfig){
				clazz.basedata={};
				for(var e in exconfig){
					var ex=exconfig[e];
					if(typeof ex!='object'||e!='scope'){
						cp[e]=ex;
					}else{//object类型数据，此数据在实例化的时候，为每个实例化对象复制一份拷贝，防止多个对象共享数据导致错乱
						clazz.basedata[e]=ex;
					}
				}
			}
			Mui.apply(clazz.prototype,cp);
			
			return clazz;
		},
		/**
		*@desc 类重写
		*param ac
		*/
		override:function(ac,overrides){
			var p=ac.prototype;
			for(var method in overrides){
				p[method]=overrides[method];
			}
		},
		/**
		*@desc 生成ID
		*/
		createId:function(prix,length){
			prix=prix||'';
			prix+=(prix.substr(0,2)=='x_')?'':'x_';
			prix+=(prix.substr(prix.length-1,1)=='_')?'':'_';
			
			length=length||8;
			var _x=Math.random()*Math.pow(10, length)+'';
			return prix+_x.substr(0,_x.indexOf('.'));
		},
		/**		
		*@desc 格式化，同C#的format
		*@return 第一个参数是格式化的字符串，第二个参数是参数
		*/
		format : function(format){
			var args = Array.prototype.slice.call(arguments, 1);
			return format.replace(/\{(\d+)\}/g, function(m, i){
				return args[i];
			});
		},	
		/**
		*@desc 格式化
		*@param p: <input id="{id}" name="{name}" class="{cls}"/>
		*@param d:{
			id:'a_email',
			name:'email',
			class:'mui-email'
		}
		*@return <input id="a_email" name="email" class="mui-email"/>
		*/
		parse:function(p,d){
			var reg
			for(var i in d){
				reg=new RegExp('{'+i+'}','g');
				
				p=p.replace(reg,d[i]);
			}
			return p;
		},
		/**
		*@desc 空函数
		*/
		emptyFn:function(){},
		/**
		*@desc 用户配置函数，用于返回相应的配置数据，执行前先判断
		*/
		configFn:undefined,	
		/**		
		*@desc 获取浏览器信息
		*@return 浏览器信息
		*/
		getNavInfo:function(){
			var ua = navigator.userAgent.toLowerCase(),
			check = function(r){
				return r.test(ua);
			},
			navInfo={};
			
			navInfo.isStrict = document.compatMode == "CSS1Compat";
			navInfo.isOpera = check(/opera/);
			navInfo.isChrome = check(/chrome/);
			navInfo.isWebKit = check(/webkit/);
			navInfo.isSafari = !navInfo.isChrome && check(/safari/);
			navInfo.isSafari2 = navInfo.isSafari && check(/applewebkit\/4/); // unique to Safari 2
			navInfo.isSafari3 = navInfo.isSafari && check(/version\/3/);
			navInfo.isSafari4 = navInfo.isSafari && check(/version\/4/);
			navInfo.isIE = !navInfo.isOpera && check(/msie/);
			navInfo.isIE7 = navInfo.isIE && check(/msie 7/);
			navInfo.isIE8 = navInfo.isIE && check(/msie 8/);
			navInfo.isIE6 = navInfo.isIE && !navInfo.isIE7 && !navInfo.isIE8;
			navInfo.isGecko = !navInfo.isWebKit && check(/gecko/);
			navInfo.isGecko2 = navInfo.isGecko && check(/rv:1\.8/);
			navInfo.isGecko3 = navInfo.isGecko && check(/rv:1\.9/);
			navInfo.isBorderBox = navInfo.isIE && !navInfo.isStrict;
			navInfo.isWindows = check(/windows|win32/);
			navInfo.isMac = check(/macintosh|mac os x/);
			navInfo.isAir = check(/adobeair/);
			navInfo.isLinux = check(/linux/);
			navInfo.isSecure = /^https/i.test(window.location.protocol);
			return navInfo;
		},
		/**
		*@desc 获取页面可用尺寸大小
		*/
		getPageSize:function(){
			if(window.innerHeight){
				var w=document.body.offsetWidth;
				//var wi=window.innerWidth;
				return {
					width:w,
					height:window.innerHeight
				}
			}else if(document.documentElement&&document.documentElement.clientHeight){
				return {
					width:document.documentElement.clientWidth,
					height:document.documentElement.clientHeight
				}
			}else{
				return {
					width:document.body.offsetWidth,
					height:document.body.offsetHeight
				}
			}
		},
		/**
		*@desc 判断一个对象是否是数组
		*@param a 需要判断的对象
		*/
		isArray:function(a){
			return (typeof a=='object')&&(a instanceof Array);
		},
		/**
		*@desc 判断是否是对象，不包括null
		*/
		isObject:function(o){
			return o&&typeof o =='object' && !(o instanceof Array);
		},
		/**
		*@desc 判断是否是字符串
		*/
		isString:function(o){
			return typeof o =='string';
		},
		/**
		*@desc 判断是否是function
		*/
		isFunction:function(o){
			return typeof o == 'function';
		},
		/**
		*@desc 判断是否是数字
		*/
		isNum:function(o){
			return typeof o == 'number';
		},
		type:function(o){
			if(o===null){
				return 'null';
			}
			if(o===undefined){
				return 'undefined';
			}
			return Mui.isArray(o)?'array':typeof o;
		},
		/**
		*@desc 对对象做遍历操作
		*/
		each:function(o,cb,sc){
			if(Mui.isArray(o)){
				for(var i=0,len=o.length;i<len;i++){
					cb.call(sc||o,i,o[i]);
				}
			}else if(Mui.isObject(o)){
				for(var oo in o){
					cb.call(sc||o,oo,o[oo]);
				}
			}
		},
		/**
		*@desc 获取url地址中的参数
		*@param key 要获取的参数的名称
		*@return val 要获取的参数的值，没有返回null
		*/
		getQuery:function(key) {
			var str = decodeURI(window.location.search);
			var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)", "i");
			var r = str.substr(1).match(reg);
			if (r != null) {
				return unescape(r[2]);
			} else {
				return null;
			}
		}
	
	});
	/**
	*@desc 获取浏览器信息
	*/
	Mui.na=Mui.getNavInfo();
	/**
	*@desc 判断浏览器是否使用的是IE的盒子模型
	*/
	Mui.ieBox=Mui.backCompat&&Mui.na.isIE;

	
})();

/**@desc 添加对ready方法的支持*/
(function(){
	var readyFnList=[],isReady=false;
	var runReady=function(){
		for(var i=0,len=readyFnList.length;i<len;i++){
			readyFnList[i](Mui);
		}
	}
	if(window.attachEvent){
		window.attachEvent('onload',function(){
			isReady=true;
			runReady();
		});
	}else if(window.addEventListener){
		window.addEventListener('load',function(){
			isReady=true;
			runReady();
		});
	}else{
		window.onload=function(){
			isReady=true;
			runReady();
		}
	}
	
	Mui.ready=function(fn){
		if(!fn){
			return;
		}
		if(isReady){//if is ready,do function right now
			fn(Mui);
			return;
		}
		readyFnList.push(fn);
	}
})();

/***@desc loader 定义*/
(function(){	
	var __loaded={};
	
	var loadJS=function(src,cb,doc){
		cb=cb||function(){};
		if(__loaded[src]||(!src)){
			cb();
			return;
		}
		doc=doc||document;		
		var s=doc.createElement('script');
		s.type='text/javascript';
		if(Mui.timeSeed){
			s.src=src+'?'+(new Date());
		}else{
			s.src=src;
		}
		s.onreadystatechange=s.onload=function(){
			if(!this.readyState||(this.readyState=='complete'||this.readyState=='loaded')){
				__loaded[src]=true;
				cb();
				if(window.console){
					console.log(src+' is loaded!');
				}
			}
		};
		doc.getElementsByTagName('head')[0].appendChild(s);
		return s;
	}
	var loadCSS=function(href,doc){
		if(__loaded[href]){
			return;
		}
		doc=doc||document;
		var l=doc.createElement('link');
		l.type='text/css';
		if(Mui.timeSeed){
			l.href=href+'?'+(new Date());
		}else{
			l.href=href;
		}
		l.rel='stylesheet';
		doc.getElementsByTagName('head')[0].appendChild(l);
		__loaded[href]=true;
		return l;
	}
	
	var Query=function(){};
	Query.prototype={
		query:[],
		isLoading:false,
		isArray:function(o){
			return o.constructor===Array;
		},
		add:function(items,cb){
			if(this.isArray(items)){
				this.query.concat(items);
			}else{
				this.query.push(items);
			}
			if(cb){
				this.query.push(cb);
			}
		},
		next:function(){
			return this.query.shift();
		},
		start:function(isUse){
			if(isUse&&this.isLoading){
				return;
			}
			this.isLoading=true;
			var c=this.next();
			if(!c){
				this.isLoading=false;
				return;
			}
			if(typeof(c)=='function'){//did cb
				c(this);
				this.start();
				return;
			}
			this.run.call(this,c,this);
		},
		run:function(item,query){}
	}
	
	var getPath=function(prev){
		var js=document.scripts;
		js=js[js.length-1].src;
		js=js.substring(0,js.lastIndexOf("/"));
		prev=prev||0;
		while(prev){
			js=js.substring(0,js.lastIndexOf("/"));
			prev--;
		}
		return js;
	};
	var getRequires=function(mods,lib){
		if(!mods){
			return {
				js:[],
				css:[],
				name:[]
			};
		}
		mods=mods.split(',');
		var js=[],css=[],name=[];
		for(var i=0,len=mods.length;i<len;i++){
			var mod=lib[mods[i]];
			if(mod&&!mod.loaded){
				if(mod.requires){
					var res=getRequires(mod.requires,lib);
					js=js.concat(res.js);
					css=css.concat(res.css);
					name=name.concat(res.name);
				}
				js=js.concat(mod.js);
				js.push((function(m){
					return function(){
						m.loaded=true;
					}
				})(mod))
				css=css.concat(mod.css);
				name.push(mod.name);
				//mod.loaded=true;
			}
		}
		return {
			js:js,
			css:css,
			name:name
		};
	}
	var joinStr=function(split){
		var s=[];
		for(var i=1,len=arguments.length;i<len;i++){
			if(arguments[i]!==undefined){
				s.push(arguments[i]);
			}
		}
		return s.join('/');
	}
	
	Mui.ns('Mui.loader');
	Mui.apply(Mui.loader,{
		isReady:false,
		lib:{
			'def':{
				path:getPath(1)
			}
		},
		initModsQuery:function(){
			this.query=new Query();
			this.query.run=function(mod,query){
					var js=mod.js;
					var loadingQuery=new Query();
					loadingQuery.query=js;
					loadingQuery.query.push(function(q){
						query.start();
					});
					loadingQuery.run=function(item,lq){
						Mui.loader.loadJS(item,function(){
							lq.start();
						});
					}
					loadingQuery.start(true);
					Mui.loader.loadCSS(mod.css);
			};
			return this;
		},
		loadJS:function(src,cb,doc){
			if(!src){
				return;
			}
			var lc=0;
			if(typeof(src)=='string'){
				src=src.split(',');
			}
			for(var i=0,len=src.length;i<len;i++){
				loadJS(src[i],function(_src){
					lc++;
					if(lc==len){
						cb();
					}
				});
			}
		},
		loadCSS:function(href,doc){
			if(!href){
				return;
			}
			if(typeof(href)=='string'){
				href=href.split(',');
			}
			for(var i=0,len=href.length;i<len;i++){
				loadCSS(href[i],doc);
			}
		},
		use:function(mods,cb,sc,libName){
			if(!mods){
				return;
			}
			cb=cb||function(){};
			var res=this.getRequire(mods,libName);
			
			if(!res.js.length&&!res.css.length){//all loaded
				cb.call(sc||this,Mui);
			}else{
				this.query.add({
					js:res.js,
					css:res.css
				},function(){
					cb.call(sc||this,Mui);
				});
				if(this.isReady){
					this.query.start(true);
				}
			}
		},
		bindReady:function(){
			var _this=this;
			if(window.attachEvent){
				window.attachEvent('onload',function(){
					_this.ready();
				},false);
			}else if(window.addEventListener){
				window.addEventListener('load',function(){
					_this.ready();
				},false);
			}else{
				window.onload=fn;
			}
		},
		ready:function(){
			this.isReady=true;
			this.query.start(true);
		},
		getRequire:function(mods,libName){
			if(!mods){
				return;
			}
			var lib=this.getLib(libName);
			return getRequires(mods,lib);
		},
		/**
		*@desc 添加库
		*/
		addLib:function(name,lib){
			if(!this.lib[name]){
				this.mods[name]=lib||{
					path:''
				};
			}
		},
		/**
		*@desc 获取lib库，默认返回def
		*@param libName lib库的名称
		*/
		getLib:function(libName){
			libName=libName||'def';
			this.addLib(libName);
			return this.lib[libName];
		},
		add:function(name,mod){
			if(!name){
				return;
			}
			var lib=this.getLib(mod.lib);
			var js=[],css=[];	
			var path=mod.path||(Mui.debug?'debug':'min')
			var p=joinStr('/',lib.path,path,'');
			
			if(mod.jsFullPath){
				js=mod.jsFullPath.split(',');
			}else{
				var jp=mod.jsPath;
				if(jp){
					jp=jp.split(',');
					for(var i=0,len=jp.length;i<len;i++){
						js.push(p+jp[i]);
					}
				}else if(mod.jsPath===undefined){//default;
					js.push(p+name.toLowerCase()+'.js');
				}
			}
			
			p=joinStr('/',lib.path,mod.path||'');
			
			if(mod.cssFullPath){
				css=mod.cssFullPath.split(',');
			}else{
				var cp=mod.cssPath;
				if(cp){
					cp=cp.split(',');
					for(var i=0,len=cp.length;i<len;i++){
						css.push(p+cp[i]);
					}
				}
			}
			mod.js=js;
			mod.css=css;
			mod.name=name;
			lib[name]=mod;
			return;
		}
	});
	
	Mui.loader.initModsQuery().bindReady();
})();

/***@desc 懒加载模式 定义*/
(function(){
	Mui.apply(Mui,{
		skin:'default',	//皮肤样式名称
		debug:true,
		timeSeed:true,	//是否在JS文件后面添加时间参数
		use:function(s,cb,sc,ln){
			Mui.loader.use(s,cb,sc,ln);
		},
		regist:function(name,mod){
			Mui.loader.add(name,mod||{});
		}
	});
})();


Mui.regist('Mui.json');
Mui.regist('Mui.Object',{
	requires:Mui.skin
});
Mui.regist('default',{
	jsPath:'',
	cssPath:'skins/default/mui-all.css'
});
Mui.regist('resource',{
	path:'resources',
	jsPath:'jquery-1.6.min.js,jquery-plug.js'
});
Mui.regist('Mui.ajax',{
	requires:'Mui.json'
});
Mui.regist('Mui.data.StaticStore',{
	requires:'Mui.Object'
});
Mui.regist('Mui.data.Store',{
	requires:'Mui.data.StaticStore,Mui.ajax'
});
Mui.regist('Mui.util.Component',{
	requires:'resource,Mui.Object'
});
Mui.regist('Mui.util.Panel',{
	requires:'Mui.util.Component,Mui.util.Overlay,Mui.util.Button,Mui.util.Toolbar'
});
Mui.regist('Mui.util.Window',{
	requires:'Mui.util.Panel'
});
Mui.regist('Mui.util.Grid',{
	requires:'Mui.util.Panel,Mui.data.StaticStore,Mui.util.Pagebar'
});
Mui.regist('Mui.util.JsonGrid',{
	requires:'Mui.util.Grid,Mui.data.Store'
});
Mui.regist('Mui.util.Tree',{
	requires:'Mui.util.Panel,Mui.data.StaticStore'
});
Mui.regist('Mui.util.AjaxTree',{
	requires:'Mui.util.Tree,Mui.data.Store'
});
Mui.regist('Mui.util.Layout',{
	requires:'Mui.util.Component'
});
Mui.regist('Mui.util.Overlay',{
	requires:'Mui.util.Component'
});
Mui.regist('Mui.util.Viewport',{
	requires:'Mui.util.Component,Mui.util.Panel'
});
Mui.regist('Mui.util.Pagebar',{
	requires:'Mui.util.Component'
});
Mui.regist('Mui.util.Tab',{
	requires:'Mui.util.Component'
});
Mui.regist('Mui.util.Toolbar',{
	requires:'Mui.util.Component'
});
Mui.regist('Mui.util.Button',{
	requires:'Mui.util.Component'
});
Mui.regist('Mui.msg',{
	requires:'Mui.msg.Dialog'
});
Mui.regist('Mui.msg.Dialog',{
	requires:'Mui.util.Window'
});
Mui.regist('Mui.tip',{
	requires:'Mui.tip.Dialog'
});
Mui.regist('Mui.tip.Dialog',{
	requires:'Mui.util.Component,Mui.util.Overlay'
});
Mui.regist('Mui.form.base',{
	requires:'Mui.Object,Mui.validate'
});
Mui.regist('Mui.form.combo',{
	requires:'Mui.util.Component'
});
Mui.regist('Mui.validate',{
	requires:'resource,Mui.ajax'
});
Mui.regist('Mui.util.Menu',{
	requires:'Mui.util.Component'
});

